/* cluster.h */

#ifndef _CLUSTER_H_

#define _CLUSTER_H_

#include "../common/improve_div.h"

/*
 * Representing a sub group of P
 */
typedef struct sub_group
{
	/* The elements in this group */
	int* elements;
	/* The number of elements */
	int elements_no;
	/* Indicates whether the current group is divisible */
	int is_divisible;
	/* The next sub group in P */
	struct sub_group *next;

}sub_group;

/*
 *	Creating the initial P, taking into consideration the isolated vertices
 *	-----------------------------------------------------------------------
 *	A: The adjacency matrix
 *	P: The result linked list of sub groups
 *	return: Pointer to the last sub group of P
 *	-------------------------------------------------------
 *	(!) The user is responsible of releasing the sub groups
 */
sub_group* create_initial_P(sparse_matrix_lst* A, sub_group** P);

/*
 *	Releasing a linked list of sub groups
 *	-----------------------------------------
 *	P: The sub group to be released
 */
void free_P(sub_group* P);

/*
 *	Adding a sub grop to P
 *	----------------------
 *	P: The list to add the sub group to
 *	last_sub_group: Pointer to the last sub group in the linked list
 *	group_to_add: The sub group to add
 */
void add_to_P(sub_group **P, sub_group **last_sub_group,
			  sub_group *group_to_add);

/*
 *	Filling a sub group with given parameters
 *	-----------------------------------------
 *	new_sub_group: The sub group to be filled
 *	elements: The vector of elements for this sub group
 *	elements_no: The number of elements for this sub group
 */
void fill_sub_group(sub_group *new_sub_group, int *elements, int elements_no);

/*
 *	Printing P ordered by first element of each sub group
 *	-----------------------------------------------------
 *	P: The list to print
 *	A_n: The total number of nodes
 */
void print_P(sub_group* P, int A_n);

/*
 *	Finds the next group to print according to its first element
 *	------------------------------------------------------------
 *	P: The list to search in
 *	first_index: The first group element we look for
 *	return: Pointer to the required sub group
 */
sub_group* find_group_to_print(sub_group *P, int first_index);

/*
 *	Printing a sub group
 *	--------------------
 *	group: The sub group to print
 */
void print_sub_group(sub_group* group);

/*
 *	Counting the elements in a linked list of sub groups
 *	----------------------------------------------------
 *	P: Pointer to the head of the linked list
 *	return: The number of elements in this list
 */
int count_elements(sub_group *P);

#endif 
